#pragma once 
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <iostream>
#include <unordered_map>
#include <string>
#include <vector>

using namespace std;

#include "Connect.hpp"

//key:value的储存形式来储存信息

//个人信息结构
class UserInfo
{
    public:
        UserInfo(const string& name,const string& school,const string& passwd,uint32_t id)
        {
            name_ = name;
            school_ = school;
            passwd_ = passwd;
            id_ = id;
            user_status_ = REGISTER_FAILED;
            memset((void*)&addr_,'\0',sizeof(struct sockaddr_in));
            len_ = 0;
        }
        ~UserInfo()
        {
            
        }

        string& GetPasswd()
        {
            return passwd_;
        }

        void SetStatus(int status)
        {
            user_status_ = status;
        }

        int GetStatus()
        {
            return user_status_;
        }

        void SetaddrInfo(struct sockaddr_in addr)
        {
            addr_ = addr;
        }

        void SetaddrlenInfo(socklen_t len)
        {
            len_ = len;
        }

        struct sockaddr_in& GetAddrInfo()
        {
            return addr_;
        }

        socklen_t GetAddrLen()
        {
            return len_;
        }
    private:
        //姓名，学校，密码，用户id
        string name_;
        string school_;
        string passwd_;
        uint32_t id_;
        int user_status_;
        struct sockaddr_in addr_;
        socklen_t len_;
};

//用户管理类
class UserManager
{
    public:
        UserManager()
        {
           pthread_mutex_init(&map_lock_,NULL);
           user_map_.clear();
           prepare_id_ = 0; 
           Online_user_.clear();
        }
        ~UserManager()
        {
            pthread_mutex_destroy(&map_lock_);
        }
        //处理注册
        int DealRegister(const string& name,const string& school,const string& passwd,uint32_t* id)
        {
            //判断注册信息字段是否为空
            if(school.size() == 0 || name.size() == 0 || passwd.size() == 0)
            {
                return -1;
            }
            //个人信息填充
            pthread_mutex_lock(&map_lock_); 
            UserInfo ui(name,school,passwd,prepare_id_);
            //插入map中
            user_map_.insert(make_pair(prepare_id_,ui));
            *id = prepare_id_;
            //更新id值
            prepare_id_++;
            pthread_mutex_unlock(&map_lock_);
            return 0; 
        }
        //处理登录
        int DealLogin(uint32_t id,const string& passwd)
        {
            //1.判断字段是否为空
            if(passwd.size() == 0)
            {
                return -1;
            }
            //2.找id，如果在map中没有id值，就为错误
            //  如果有，就查找密码，匹配是否正确
            std::unordered_map<uint32_t,UserInfo>::iterator iter;
            pthread_mutex_lock(&map_lock_);
            iter = user_map_.find(id);
            if(iter == user_map_.end())
            {
                pthread_mutex_unlock(&map_lock_);
                return -2;
            }
            string ret = iter->second.GetPasswd();
            if(ret != passwd)
            {
                pthread_mutex_unlock(&map_lock_);
                return -3;
            }

            pthread_mutex_unlock(&map_lock_);
            
            return 0;
            
        }
        int IsLogin(uint32_t id,struct sockaddr_in addr,socklen_t addr_len)
        {
            //使用id进行查询
            std::unordered_map<uint32_t,UserInfo>::iterator iter;
            pthread_mutex_lock(&map_lock_);
            iter = user_map_.find(id);
            if(iter == user_map_.end())
            {
                pthread_mutex_unlock(&map_lock_);
                return -1;
            }
            //判断用户状态
            //第一次发送，则我们保存该用户的地址信息
            //如果n次发送，则不用添加
            if(iter->second.GetStatus() <= LOGIN_FAILED)
            {
                pthread_mutex_unlock(&map_lock_);
                return -1;
            }

            else if(iter->second.GetStatus() == LOGIN_SUCCESS)
            {
                cout << "test islogin" << endl; 
                //第一次发送udp消息（刚刚登录）
                iter->second.SetStatus(ONLINE);
                iter->second.SetaddrInfo(addr);
                iter->second.SetaddrlenInfo(addr_len);
               //将用户添加到在线用户中去
               Online_user_.push_back(iter->second);
            }
            pthread_mutex_unlock(&map_lock_);
            return 0;
        }

        void GetOnlineUser(vector<UserInfo>* vec)
        {
            *vec = Online_user_;
        }
    private:
        //存储信息unordered_map
        std::unordered_map<uint32_t, UserInfo> user_map_;
        //预id值
        uint32_t prepare_id_;
        //互斥锁 来保护id和map的
        pthread_mutex_t map_lock_;
        vector<UserInfo> Online_user_;

};





